var storage = window.localStorage,store,_api,even_storage=function(){};

function isJSON(obj){
    return typeof(obj) === "object" && Object.prototype.toString.call(obj).toLowerCase() === "[object object]" && !obj.length;
}
function stringify (val) {
    return val === undefined || typeof val === "function" ? val+'' : JSON.stringify(val);
}
function deserialize(value){
    if (typeof value !== 'string') { return undefined ;}
    try { return JSON.parse(value) ;}
    catch(e) { return value || undefined ;}
}
function isFunction(value) { return ({}).toString.call(value) === "[object Function]";}
function isArray(value) { return value instanceof Array;}


function Store(){
    if(!(this instanceof Store)){
        return new Store();
    }
}

Store.prototype = {
    set: function(key, val){
        even_storage('set',key,val);
        if(key&&!isJSON(key)){
            storage.setItem(key, stringify(val));
        }else if(key&&isJSON(key)&&!val){
            for (var a in key) this.set(a, key[a]);
        }
        return this;
    },
    get: function(key){
        if(!key) {
            var ret = {};
            this.forEach(function(key, val) {
                ret[key] = val;
            });
            return ret;
        }
        return deserialize(storage.getItem(key));
    },
    clear: function(){
        this.forEach(function(key, val) {
            even_storage('clear',key,val);
        });
        storage.clear();
        return this;
    },
    remove: function(key) {
        var val = this.get(key);
        storage.removeItem(key);
        even_storage('remove',key,val);
        return val;
    },
    has:function(key){return storage.hasOwnProperty(key);},
    keys:function(){
        var d=[];
        this.forEach(function(k, list){
            d.push(k);
        });
        return d;
    },
    size: function(){ return this.keys().length;},
    forEach: function(callback) {
        for (var i=0; i<storage.length; i++) {
            var key = storage.key(i);
            if(callback(key, this.get(key))===false) break;
        }
        return this;
    },
    search: function(str) {
        var arr = this.keys(),dt= {};
        for (var i = 0; i < arr.length; i++) {
            if(arr[i].indexOf(str)>-1) dt[arr[i]]=this.get(arr[i]);
        }
        return dt;
    },
    onStorage: function(cb){
        if(cb && isFunction(cb)) even_storage = cb;
        return this;
    }
}

store = function(key, data){
    var argm = arguments,_Store = Store(),dt = null;
    if(argm.length ===0) return _Store.get();
    if(argm.length ===1){
        if(typeof(key) === "string") return _Store.get(key);
        if(isJSON(key)) return _Store.set(key);
    }
    if(argm.length === 2 && typeof(key) === "string"){
        if(!data)return _Store.remove(key);
        if(data&&typeof(data) === "string")return _Store.set(key,data);
        if(data&&isFunction(data)) {
            dt = null
            dt = data(key,_Store.get(key))
            return dt?store.set(key, dt):store;
        }
    }
    if(argm.length === 2 && isArray(key) && isFunction(data)){
        for (var i = 0; i < key.length; i++) {
            dt = data(key[i],_Store.get(key[i]))
            store.set(key[i], dt)
        }
        return store
    }
}
for (var a in Store.prototype) store[a] = Store.prototype[a];

export default store;